AArch64: Use SSBS for CVE_2018_3639 mitigation
authorJeenu Viswambharan <[email protected]>
Thu, 15 Nov 2018 11:38:03 +0000 (11:38 +0000)
committerJeenu Viswambharan <[email protected]>
Mon, 10 Dec 2018 14:28:58 +0000 (14:28 +0000)
The Armv8.5 extensions introduces PSTATE.SSBS (Speculation Store Bypass
Safe) bit to mitigate against Variant 4 vulnerabilities. Although an
Armv8.5 feature, this can be implemented by CPUs implementing earlier
version of the architecture.

With this patch, when both PSTATE.SSBS is implemented and
DYNAMIC_WORKAROUND_CVE_2018_3639 is active, querying for
SMCCC_ARCH_WORKAROUND_2 via. SMCCC_ARCH_FEATURES call would return 1 to
indicate that mitigation on the PE is either permanently enabled or not
required.

When SSBS is implemented, SCTLR_EL3.DSSBS is initialized to 0 at reset
of every BL stage. This means that EL3 always executes with mitigation
applied.

For Cortex A76, if the PE implements SSBS, the existing mitigation (by
using a different vector table, and tweaking CPU ACTLR2) is not used.

Change-Id: Ib0386c5714184144d4747951751c2fc6ba4242b6
Signed-off-by: Jeenu Viswambharan <[email protected]>
include/common/aarch32/el3_common_macros.S
include/common/aarch64/el3_common_macros.S
include/lib/aarch32/arch.h
include/lib/aarch64/arch.h
lib/cpus/aarch64/cortex_a76.S
services/arm_arch_svc/arm_arch_svc_setup.c

index 9b18ba38e391985ad5946b04c1a0ae47f0785a67..2438423207032adc9f91936b7aaedce1242eef21 100644 (file)
                 *
                 * SCTLR.V: Set to zero to select the normal exception vectors
                 *  with base address held in VBAR.
+                *
+                * SCTLR.DSSBS: Set to zero to disable speculation store bypass
+                *  safe behaviour upon exception entry to EL3.
                 * -------------------------------------------------------------
                 */
-               ldr     r0, =(SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_EE_BIT | SCTLR_V_BIT))
+               ldr     r0, =(SCTLR_RESET_VAL & ~(SCTLR_TE_BIT | SCTLR_EE_BIT | \
+                               SCTLR_V_BIT | SCTLR_DSSBS_BIT))
                stcopr  r0, SCTLR
                isb
        .endif /* _init_sctlr */
index adfb54e6f70a7bdf7001c762a7ee7a5f51925e9c..008daca9e79453f6a37629900c8ae3b7df0df364 100644 (file)
                 * SCTLR_EL3.SA: Set to zero to disable Stack Alignment check.
                 *
                 * SCTLR_EL3.A: Set to zero to disable Alignment fault checking.
+                *
+                * SCTLR.DSSBS: Set to zero to disable speculation store bypass
+                *  safe behaviour upon exception entry to EL3.
                 * -------------------------------------------------------------
                 */
                mov_imm x0, (SCTLR_RESET_VAL & ~(SCTLR_EE_BIT | SCTLR_WXN_BIT \
-                               | SCTLR_SA_BIT | SCTLR_A_BIT))
+                               | SCTLR_SA_BIT | SCTLR_A_BIT | SCTLR_DSSBS_BIT))
                msr     sctlr_el3, x0
                isb
        .endif /* _init_sctlr */
index 3e5e3fbf3df14a90d7e02012fd89b7de166ac064..fa6e5dbdde3b41dff4c1b63f39a699180745a367 100644 (file)
 #define SCTLR_TRE_BIT          (U(1) << 28)
 #define SCTLR_AFE_BIT          (U(1) << 29)
 #define SCTLR_TE_BIT           (U(1) << 30)
+#define SCTLR_DSSBS_BIT                (U(1) << 31)
 #define SCTLR_RESET_VAL         (SCTLR_RES1 | SCTLR_NTWE_BIT |         \
                                SCTLR_NTWI_BIT | SCTLR_CP15BEN_BIT)
 
index d7867bcdc8b2d5725a0be785909612f87c563eab..97595e9a2f81c50068919a9fbe222dfe71680476 100644 (file)
 #define ID_AA64MMFR0_EL1_TGRAN16_SUPPORTED     ULL(0x1)
 #define ID_AA64MMFR0_EL1_TGRAN16_NOT_SUPPORTED ULL(0x0)
 
+/* ID_AA64PFR1_EL1 definitions */
+#define ID_AA64PFR1_EL1_SSBS_SHIFT     U(4)
+#define ID_AA64PFR1_EL1_SSBS_MASK      ULL(0xf)
+
+#define SSBS_UNAVAILABLE       ULL(0)  /* No architectural SSBS support */
+
 /* ID_PFR1_EL1 definitions */
 #define ID_PFR1_VIRTEXT_SHIFT  U(12)
 #define ID_PFR1_VIRTEXT_MASK   U(0xf)
                        (U(1) << 22) | (U(1) << 18) | (U(1) << 16) | \
                        (U(1) << 11) | (U(1) << 5) | (U(1) << 4))
 
-#define SCTLR_M_BIT            (U(1) << 0)
-#define SCTLR_A_BIT            (U(1) << 1)
-#define SCTLR_C_BIT            (U(1) << 2)
-#define SCTLR_SA_BIT           (U(1) << 3)
-#define SCTLR_SA0_BIT          (U(1) << 4)
-#define SCTLR_CP15BEN_BIT      (U(1) << 5)
-#define SCTLR_ITD_BIT          (U(1) << 7)
-#define SCTLR_SED_BIT          (U(1) << 8)
-#define SCTLR_UMA_BIT          (U(1) << 9)
-#define SCTLR_I_BIT            (U(1) << 12)
-#define SCTLR_V_BIT            (U(1) << 13)
-#define SCTLR_DZE_BIT          (U(1) << 14)
-#define SCTLR_UCT_BIT          (U(1) << 15)
-#define SCTLR_NTWI_BIT         (U(1) << 16)
-#define SCTLR_NTWE_BIT         (U(1) << 18)
-#define SCTLR_WXN_BIT          (U(1) << 19)
-#define SCTLR_UWXN_BIT         (U(1) << 20)
-#define SCTLR_E0E_BIT          (U(1) << 24)
-#define SCTLR_EE_BIT           (U(1) << 25)
-#define SCTLR_UCI_BIT          (U(1) << 26)
-#define SCTLR_TRE_BIT          (U(1) << 28)
-#define SCTLR_AFE_BIT          (U(1) << 29)
-#define SCTLR_TE_BIT           (U(1) << 30)
+#define SCTLR_M_BIT            (ULL(1) << 0)
+#define SCTLR_A_BIT            (ULL(1) << 1)
+#define SCTLR_C_BIT            (ULL(1) << 2)
+#define SCTLR_SA_BIT           (ULL(1) << 3)
+#define SCTLR_SA0_BIT          (ULL(1) << 4)
+#define SCTLR_CP15BEN_BIT      (ULL(1) << 5)
+#define SCTLR_ITD_BIT          (ULL(1) << 7)
+#define SCTLR_SED_BIT          (ULL(1) << 8)
+#define SCTLR_UMA_BIT          (ULL(1) << 9)
+#define SCTLR_I_BIT            (ULL(1) << 12)
+#define SCTLR_V_BIT            (ULL(1) << 13)
+#define SCTLR_DZE_BIT          (ULL(1) << 14)
+#define SCTLR_UCT_BIT          (ULL(1) << 15)
+#define SCTLR_NTWI_BIT         (ULL(1) << 16)
+#define SCTLR_NTWE_BIT         (ULL(1) << 18)
+#define SCTLR_WXN_BIT          (ULL(1) << 19)
+#define SCTLR_UWXN_BIT         (ULL(1) << 20)
+#define SCTLR_E0E_BIT          (ULL(1) << 24)
+#define SCTLR_EE_BIT           (ULL(1) << 25)
+#define SCTLR_UCI_BIT          (ULL(1) << 26)
+#define SCTLR_TRE_BIT          (ULL(1) << 28)
+#define SCTLR_AFE_BIT          (ULL(1) << 29)
+#define SCTLR_TE_BIT           (ULL(1) << 30)
+#define SCTLR_DSSBS_BIT                (ULL(1) << 44)
 #define SCTLR_RESET_VAL                SCTLR_EL3_RES1
 
 /* CPACR_El1 definitions */
index 1697c55dc87aa34a63632312226c07315f671f41..4def14373754b6efe53c8404bb762079a992d586 100644 (file)
@@ -208,14 +208,20 @@ endfunc cortex_a76_disable_wa_cve_2018_3639
 
 func cortex_a76_reset_func
        mov     x19, x30
+
 #if WORKAROUND_CVE_2018_3639
+       /* If the PE implements SSBS, we don't need the dynamic workaround */
+       mrs     x0, id_aa64pfr1_el1
+       lsr     x0, x0, #ID_AA64PFR1_EL1_SSBS_SHIFT
+       and     x0, x0, #ID_AA64PFR1_EL1_SSBS_MASK
+       cbnz    x0, 1f
+
        mrs     x0, CORTEX_A76_CPUACTLR2_EL1
        orr     x0, x0, #CORTEX_A76_CPUACTLR2_EL1_DISABLE_LOAD_PASS_STORE
        msr     CORTEX_A76_CPUACTLR2_EL1, x0
        isb
-#endif
 
-#if IMAGE_BL31 && WORKAROUND_CVE_2018_3639
+#ifdef IMAGE_BL31
        /*
         * The Cortex-A76 generic vectors are overwritten to use the vectors
         * defined above.  This is required in order to apply mitigation
@@ -226,6 +232,9 @@ func cortex_a76_reset_func
        isb
 #endif
 
+1:
+#endif
+
 #if ERRATA_DSU_936184
        bl      errata_dsu_936184_wa
 #endif
index 45c4704eed0567b3ab1b3ad7a551a685309c049c..3a5299fdf3039a1303a12d30addcd0634ed3522c 100644 (file)
@@ -30,9 +30,27 @@ static int32_t smccc_arch_features(u_register_t arg)
                        return 1;
                return 0; /* ERRATA_APPLIES || ERRATA_MISSING */
 #endif
+
 #if WORKAROUND_CVE_2018_3639
-       case SMCCC_ARCH_WORKAROUND_2:
+       case SMCCC_ARCH_WORKAROUND_2: {
 #if DYNAMIC_WORKAROUND_CVE_2018_3639
+               unsigned long long ssbs;
+
+               /*
+                * Firmware doesn't have to carry out dynamic workaround if the
+                * PE implements architectural Speculation Store Bypass Safe
+                * (SSBS) feature.
+                */
+               ssbs = (read_id_aa64pfr0_el1() >> ID_AA64PFR1_EL1_SSBS_SHIFT) &
+                       ID_AA64PFR1_EL1_SSBS_MASK;
+
+               /*
+                * If architectural SSBS is available on this PE, no firmware
+                * mitigation via SMCCC_ARCH_WORKAROUND_2 is required.
+                */
+               if (ssbs != SSBS_UNAVAILABLE)
+                       return 1;
+
                /*
                 * On a platform where at least one CPU requires
                 * dynamic mitigation but others are either unaffected
@@ -50,7 +68,11 @@ static int32_t smccc_arch_features(u_register_t arg)
                /* Either the CPUs are unaffected or permanently mitigated */
                return SMCCC_ARCH_NOT_REQUIRED;
 #endif
+       }
 #endif
+
+       /* Fallthrough */
+
        default:
                return SMC_UNK;
        }